﻿//-----------------------------------------------------------------------
// <copyright file="ViewModelEntityBase.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>22/07/2012</date>
//-----------------------------------------------------------------------
using ConsoleHoster.Common.Model;
using System;
using System.ComponentModel;

namespace ConsoleHoster.Common.ViewModel
{
	public abstract class ViewModelEntityBase<T> : INotifyPropertyChanged where T : IModelEntity
	{
		public event PropertyChangedEventHandler PropertyChanged;

		private readonly T model;

		public ViewModelEntityBase(T argModel)
		{
			if (argModel == null)
			{
				throw new ArgumentNullException("argModel");
			}

			this.model = argModel;
		}

		protected virtual void NotifyPropertyChange(string argPropertyName)
		{
			PropertyChangedEventHandler tmpEH = this.PropertyChanged;
			if (tmpEH != null)
			{
				tmpEH(this, new PropertyChangedEventArgs(argPropertyName));
			}
		}

		protected bool SetPropertyValue<V>(string argPropertyName, ref V argField, V argNewValue)
		{
			bool tmpResult = false;
			if (!argNewValue.Equals(argField))
			{
				argField = argNewValue;
				tmpResult = true;
				this.NotifyPropertyChange(argPropertyName);
			}

			return tmpResult;
		}

		/// <summary>
		/// This method is used for updating the underlying entity of a VM object, right before it's being requested.
		/// This will be used in the scenarios, where a VM entity defines its own set of properties, which are related to the models.
		/// So then the VM property being updated, leaving the Model object's property obsolete.
		/// Consider overriding this method in above described scenario, and updating the returning model object with data from the VM instance.
		/// </summary>
		/// <param name="argModel">The original model entity to be updated</param>
		protected virtual void OnModelRequested(T argModel)
		{
		}

		public T Model
		{
			get
			{
				this.OnModelRequested(this.model);
				return this.model;
			}
		}
	}
}
